﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CGSR.Core;
using CGSR.Simulation;

namespace CGSR.GUI
{
    public partial class Form1 : Form
    {
		private float ratio = 0;
        private BenchmarkParser bp;
        private SimulationManager simulationManager;

        //Dictionary<string,int> pairToGW = new Dictionary<string, int>();
        HashSet<int> GWs = new HashSet<int>();
		private int xOffset = 0;
		private int yOffset = 0;

    	public Form1(BenchmarkParser bp,SimulationManager sm)
        {
            this.bp = bp;
            this.simulationManager = sm;
            InitializeComponent();
            graphicalOverlay1.Owner = this;
        }

        

        private void graphicalOverlay1_Paint(object sender, PaintEventArgs e)
        {
            // This event will fire for the form and each control on the form.
            // The graphical overlay component will have already transformed the graphics object
            // to use the form's coordinate system, so no control-specific calculations are required.

            
            Rectangle rect = ClientRectangle;
            rect.Inflate(-5, -5);

            if (bp.LocationsManager.MaxX != bp.LocationsManager.MaxX)
                throw new Exception("Assumed maxX==maxY, view will be wrong");
            ratio = (float) (rect.Height/bp.LocationsManager.MaxX);

            using (Pen pen = new Pen(Color.Red, 1))
                e.Graphics.DrawRectangle(pen, rect);


            foreach (Node node in simulationManager.Nodes)
            {
                showNode(e,node);
            }

            foreach (int gw in GWs)
            {
                paintGW(e,gw);
            }
        }

        private void paintGW(PaintEventArgs e, int gw)
        {
            Node node = simulationManager.Nodes[gw];
            float screenX = node.X * ratio-xOffset;
            float screenY = node.Y * ratio-yOffset;
            using (Font font = new Font("Arial", 10))
                e.Graphics.DrawString(gw.ToString(), font, Brushes.SpringGreen, screenX, screenY);
        }

        private void showNode(PaintEventArgs e, Node node)
        {
            

            Brush brush=Brushes.Black;

            float screenX = node.X*ratio-xOffset;
            float screenY = node.Y*ratio-yOffset;

            if (node.IsCH)
            {
                brush = Brushes.Red;
				
            	e.Graphics.DrawEllipse(new Pen(brush), (node.X - bp.PacketsManager.ReceptionRadius) * ratio-xOffset, (node.Y - bp.PacketsManager.ReceptionRadius) * ratio-yOffset,
                    2 * bp.PacketsManager.ReceptionRadius * ratio, 2 * bp.PacketsManager.ReceptionRadius * ratio);

                foreach (var key in node.virtuallyneighborCHtoGw.Keys)
                {
                    if (key>node.ID)
                    {
                        float x2 = simulationManager.Nodes[key].X * ratio-xOffset;
                        float y2 = simulationManager.Nodes[key].Y * ratio-yOffset;

                        e.Graphics.DrawLine(new Pen(Color.Blue), screenX, screenY, x2, y2);
                        
                        using (Font font = new Font("Arial", 6))
                            e.Graphics.DrawString(((node.X - simulationManager.Nodes[key].X).sqr() + (node.Y - simulationManager.Nodes[key].Y).sqr()).sqrt().display(), font, Brushes.Blue, (screenX + x2) / 2, (screenY + y2) / 2);
                    }
                    foreach (var CHtoGW in node.virtuallyneighborCHtoGw)
                    {
                        GWs.Add(CHtoGW.Value);
                        //int min = Math.Min(node.ID, CHtoGW.Key);
                        //int max = Math.Max(node.ID, CHtoGW.Key);
                        //string s = min + "$" + max;
                        //if (pairToGW.ContainsKey(s))
                        //{
                        //    if (pairToGW[s]!=CHtoGW.Value)
                        //        throw new Exception();
                        //}
                        //else
                        //{
                        //     pairToGW.Add(s,CHtoGW.Value);
                        //}

                    }
                }
            }

            using (Font font = new Font("Arial", 10))
                e.Graphics.DrawString(node.ID.ToString(), font, brush, screenX, screenY);


        }

        public static Rectangle Coordinates(Control control)
        {
            Rectangle coordinates;
            Form form = (Form)control.TopLevelControl;

            if (control == form)
                coordinates = form.ClientRectangle;
            else
                coordinates = form.RectangleToClient(control.Parent.RectangleToScreen(control.Bounds));

            return coordinates;
        }

        

    }
}
